extends Node2D
class_name Tetromino

var currentTypeParentNode:Node2D
var currentTypeParentNodeIndex
var currentDirParentNode:Node2D
var currentDirParentNodeIndex
var blockSize = 16
var tetrisRegion:TetrisRegion

func setRegion(region):
	tetrisRegion = region


func initTypeDir(typeName, dirName):
	setType(typeName)
	setDir(dirName)


func initPos(pos):
	position = pos
	
	
func getHeightOffset():
	var height = 0
	var blocksData = getCurrentBlocksData()
	var differentPositionYArr = []
	
	for blockData in blocksData:
		if blockData["position"][1] >= 0 and differentPositionYArr.find(blockData["position"][1]) == -1:
			differentPositionYArr.append(blockData["position"][1])
			height += blockSize
			
	return height
			 

func setPos(pos):
	position = pos
	

func getPos():
	return position
	

func setType(typeName):
	var childCount = get_child_count()
	for index in range(childCount):
		var childNode:Node2D = get_child(index) as Node2D
		if childNode.name != typeName:
			childNode.visible = false
		else:
			childNode.visible = true
			currentTypeParentNode = childNode
			currentTypeParentNodeIndex = index
			
			
func setDir(dirName):
	var childCount = currentTypeParentNode.get_child_count()
	for index in range(childCount):
		var childNode:Node2D = currentTypeParentNode.get_child(index) as Node2D
		if childNode.name != dirName:
			childNode.visible = false
		else:
			childNode.visible = true
			currentDirParentNode = childNode
			currentDirParentNodeIndex = index
	

func getData():
	var data = {
		"position": [position.x, position.y],
		"type": currentTypeParentNode.name,
		"dir": currentDirParentNode.name,
	}
	
	data["blocks"] = getBlocksDataDir(currentDirParentNode.name)
	return data
	
	
func getCurrentBlocksData():
	return getBlocksDataDir(currentDirParentNode.name)
		
		
func getBlocksDataDir(dirName):
	var blocksData = []
	var targetDirParentNode = currentTypeParentNode.get_node(NodePath(dirName)) as Node2D
	var targetDirChildCount = targetDirParentNode.get_child_count()
	for index in range(targetDirChildCount):
		var blockNode:Block = targetDirParentNode.get_child(index) as Block
		var blockNodeData = blockNode.getData()
		var positionTrans = Vector2i(blockNode.position.x + position.x, blockNode.position.y + position.y)
		blockNodeData["positionTrans"] = [positionTrans.x, positionTrans.y]
		blockNodeData["cellPos"] = [positionTrans.x / blockSize, positionTrans.y / blockSize]
		blocksData.append(blockNodeData)
	return blocksData
	

func getBlocksDataPos(newPos):
	var blocksData = []
	var currentDirChildCount = currentDirParentNode.get_child_count()
	for index in range(currentDirChildCount):
		var blockNode:Block = currentDirParentNode.get_child(index) as Block
		var blockNodeData = blockNode.getData()
		var positionTrans = Vector2i(blockNode.position.x + newPos.x, blockNode.position.y + newPos.y)
		blockNodeData["positionTrans"] = [positionTrans.x, positionTrans.y]
		blockNodeData["cellPos"] = [positionTrans.x / blockSize, positionTrans.y / blockSize]
		blocksData.append(blockNodeData)
	return blocksData


func rotateT():
	var dirCount = currentTypeParentNode.get_child_count()
	var nextDirIndex = (currentDirParentNodeIndex + 1) if (currentDirParentNodeIndex + 1) < dirCount else 0
	var targetDirName = currentTypeParentNode.get_child(nextDirIndex).name
	var rotatable = testRotatable(targetDirName)
	if rotatable:
		setDir(targetDirName)
		GlobalSignals.MAIN_VIEW_CHANGED.emit()
		GlobalSignals.PLAY_SOUND.emit(SoundManager.TETROMINO_ROTATE)
	else:
		GlobalSignals.PLAY_SOUND.emit(SoundManager.CANT_DO)


func moveLeft():
	var blocksData = getBlocksDataPos(position + Vector2(-blockSize, 0))
	var ifBeyondLeftRight = testBeyondLeftRight(blocksData)
	var ifOverlapWithBottomBlocks = tetrisRegion.testOverlap(blocksData)
	if not ifBeyondLeftRight and not ifOverlapWithBottomBlocks:
		position += Vector2(-blockSize, 0)
		GlobalSignals.MAIN_VIEW_CHANGED.emit()
		GlobalSignals.PLAY_SOUND.emit(SoundManager.TETROMINO_MOVE)
	else:
		GlobalSignals.PLAY_SOUND.emit(SoundManager.CANT_DO)
	
	
func moveRight():
	var blocksData = getBlocksDataPos(position + Vector2(blockSize, 0))
	var ifBeyondLeftRight = testBeyondLeftRight(blocksData)
	var ifOverlapWithBottomBlocks = tetrisRegion.testOverlap(blocksData)
	if not ifBeyondLeftRight and not ifOverlapWithBottomBlocks:
		position += Vector2(blockSize, 0)
		GlobalSignals.MAIN_VIEW_CHANGED.emit()
		GlobalSignals.PLAY_SOUND.emit(SoundManager.TETROMINO_MOVE)
	else:
		GlobalSignals.PLAY_SOUND.emit(SoundManager.CANT_DO)
	
	
func moveDown():
	var blocksData = getBlocksDataPos(position + Vector2(0, blockSize))
	if not tetrisRegion.testOverlap(blocksData) and not testBeyondBottom(blocksData):
		position = position + Vector2(0, blockSize)
		GlobalSignals.MAIN_VIEW_CHANGED.emit()
		GlobalSignals.PLAY_SOUND.emit(SoundManager.TETROMINO_MOVE)
	else:
		tetrisRegion.stopAutoMoveDown()
		tetrisRegion.destroyCurrentT()
		tetrisRegion.add2BottomBlocks(getCurrentBlocksData())
		GlobalSignals.PLAY_SOUND.emit(SoundManager.TETROMINO_REACH_BOTTOM)
	

func testBeyondBottom(blocksData):
	var ifBeyond = false
	for blockData in blocksData:
		if blockData["positionTrans"][1] >= tetrisRegion.height:
			ifBeyond = true
			break
			
	return ifBeyond
	

func testBeyondLeftRight(blocksData):
	var ifBeyond = false
	for blockData in blocksData:
		if blockData["positionTrans"][0] <= -tetrisRegion.blockSize or blockData["positionTrans"][0] >= tetrisRegion.width:
			ifBeyond = true
			break
			
	return ifBeyond
	

func testRotatable(targetDirName):
	var blocksData = getBlocksDataDir(targetDirName)
	var ifOverlapWithBottomBlocks = tetrisRegion.testOverlap(blocksData)
	var ifBeyondBottom = testBeyondBottom(blocksData)
	var ifBeyondLeftRight = testBeyondLeftRight(blocksData)
	
	return not ifOverlapWithBottomBlocks and not ifBeyondBottom and not ifBeyondLeftRight
	



